<?php
/**
 * Gold Shipping Module
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * Shipping DHL
 *
 * @category    Gold
 * @package     Gold_Cshipping
 * @copyright   Copyright (c) 2011 Gold
 * @Author $Id$
*/

class Gold_Cshipping_Model_Carrier_Dhl
    extends Gold_Cshipping_Model_Carrier_Abstract
    implements Mage_Shipping_Model_Carrier_Interface
{

    protected $_code = 'golddhl';
    protected $_default_condition_name = 'package_weight';

    protected $_conditionNames = array();

    public function __construct()
    {
        parent::__construct();
        foreach ($this->getCode('condition_name') as $k=>$v) {
            $this->_conditionNames[] = $k;
        }
    }

    /**
     * Enter description here...
     *
     * @param Mage_Shipping_Model_Rate_Request $data
     * @return Mage_Shipping_Model_Rate_Result
     */
    public function collectRates(Mage_Shipping_Model_Rate_Request $request)
    {
        if (!$this->getConfigFlag('active')) {
            return false;
        }
        
        // exclude Virtual products price from Package value if pre-configured
        if (!$this->getConfigFlag('include_virtual_price') && $request->getAllItems()) {
            foreach ($request->getAllItems() as $item) {
                if ($item->getParentItem()) {
                    continue;
                }
                if ($item->getHasChildren() && $item->isShipSeparately()) {
                    foreach ($item->getChildren() as $child) {
                        if ($child->getProduct()->isVirtual() || $item->getProductType() == 'downloadable') {
                            $request->setPackageValue($request->getPackageValue() - $child->getBaseRowTotal());
                        }
                    }
                } elseif ($item->getProduct()->isVirtual() || $item->getProductType() == 'downloadable') {
                    $request->setPackageValue($request->getPackageValue() - $item->getBaseRowTotal());
                }
            }
        }
        
  		// Free shipping by qty
        $freeQty = 0;
        $freeMethodWeight = 0;
        $addressWeight = 0;
        if ($request->getAllItems()) {
        	$freeAddress = $request->getFreeShipping();
            foreach ($request->getAllItems() as $item) {            	
                if ($item->getProduct()->isVirtual() || $item->getParentItem()) {
                    continue;
                }

                if ($item->getHasChildren() && $item->isShipSeparately()) {
                    foreach ($item->getChildren() as $child) {
	                    if ($child->getProduct()->isVirtual()) {
	                        continue;
	                    }
	                    if (!$item->getProduct()->getWeightType()) {
	                    	$itemWeight2 = $this->_getItemWeight2($child->getProduct()->getId());
	                        $itemWeight = !empty($itemWeight2)&&$this->getConfigData('estimated_weight2') ? $itemWeight2 : $child->getWeight();
	                        $itemQty    = $child->getTotalQty();
	                        $rowWeight  = $itemWeight*$itemQty;
	                        $addressWeight += $rowWeight;
	                        if ($freeAddress || $child->getFreeShipping()===true) {
	                            $rowWeight = 0;
	                        } elseif (is_numeric($child->getFreeShipping())) {
	                            $freeQty = $child->getFreeShipping();
	                            if ($itemQty>$freeQty) {
	                                $rowWeight = $itemWeight*($itemQty-$freeQty);
	                            }
	                            else {
	                                $rowWeight = 0;
	                            }
	                        }
	                        $freeMethodWeight += $rowWeight;
	                        $item->setRowWeight($rowWeight);
	                    }
                        if ($child->getFreeShipping() && !$child->getProduct()->isVirtual()) {
                            $freeQty += $item->getQty() * ($child->getQty() - (is_numeric($child->getFreeShipping()) ? $child->getFreeShipping() : 0));
                        }
                    }
	                if ($item->getProduct()->getWeightType()) {
	                	$itemWeight2 = $this->_getItemWeight2($item->getProduct()->getId());
	                    $itemWeight = !empty($itemWeight2)&&$this->getConfigData('estimated_weight2') ? $itemWeight2 : $item->getWeight();
	                    $rowWeight  = $itemWeight*$item->getQty();
	                    $addressWeight+= $rowWeight;
	                    if ($freeAddress || $item->getFreeShipping()===true) {
	                        $rowWeight = 0;
	                    } elseif (is_numeric($item->getFreeShipping())) {
	                        $freeQty = $item->getFreeShipping();
	                        if ($item->getQty()>$freeQty) {
	                            $rowWeight = $itemWeight*($item->getQty()-$freeQty);
	                        }
	                        else {
	                            $rowWeight = 0;
	                        }
	                    }
	                    $freeMethodWeight+= $rowWeight;
	                    $item->setRowWeight($rowWeight);
	                }
                } else{
	                $itemWeight2 = $this->_getItemWeight2($item->getProduct()->getId());
	                $itemWeight = !empty($itemWeight2)&&$this->getConfigData('estimated_weight2') ? $itemWeight2 : $item->getWeight();
	                $rowWeight  = $itemWeight*$item->getQty();
	                $addressWeight+= $rowWeight;
	                if ($freeAddress || $item->getFreeShipping()===true) {
	                    $rowWeight = 0;
	                } elseif (is_numeric($item->getFreeShipping())) {
	                    $freeQty = $item->getFreeShipping();
	                    if ($item->getQty()>$freeQty) {
	                        $rowWeight = $itemWeight*($item->getQty()-$freeQty);
	                    }
	                    else {
	                        $rowWeight = 0;
	                    }
	                }
	                $freeMethodWeight+= $rowWeight;
	                $item->setRowWeight($rowWeight);
	                if ($item->getFreeShipping()) {
	                    $freeQty += ($item->getQty() - (is_numeric($item->getFreeShipping()) ? $item->getFreeShipping() : 0));
	              }
                }
            }
        }

        if (!$request->getConditionName()) {
            $request->setConditionName($this->getConfigData('condition_name') ? $this->getConfigData('condition_name') : $this->_default_condition_name);
        }

         // Package weight and qty free shipping
        $oldWeight = $request->getPackageWeight();
        $oldQty = $request->getPackageQty();
        $request->setPackageWeight($freeMethodWeight);
        $request->setPackageQty($oldQty - $freeQty);
        
        $result = Mage::getModel('shipping/rate_result');
     	$ratearray = $this->getRate($request);

     	$freeShipping=false;
     	
     	if (is_numeric($this->getConfigData('free_shipping_threshold')) && 
	        $this->getConfigData('free_shipping_threshold')>0 &&
	        $request->getPackageValue()>$this->getConfigData('free_shipping_threshold')) {
	         	$freeShipping=true;
	    }
    	if ($this->getConfigData('allow_free_shipping_promotions') &&
	        ($request->getFreeShipping() === true || 
	        $request->getPackageQty() == $this->getFreeBoxes()))
        {
         	$freeShipping=true;
        }
        if ($freeShipping)
        {
		  	$method = Mage::getModel('shipping/rate_result_method');
			$method->setCarrier($this->_code);
			$method->setCarrierTitle($this->getConfigData('title'));
			$method->setMethod('golddhl');
			$method->setPrice('0.00');
			$method->setMethodTitle($this->getConfigData('free_method_text'));
			$result->append($method);
			
			if ($this->getConfigData('show_only_free')) {
				return $result;
			}
		}
     	
		if ($ratearray)
		{
			foreach ($ratearray as $rate)
			{
			   if (!empty($rate) && $rate['price'] >= 0) {
				  $method = Mage::getModel('shipping/rate_result_method');
	
					$method->setCarrier($this->_code);
					$method->setCarrierTitle($this->getConfigData('title'));
	
					$method->setMethod('golddhl');
	
					$method->setMethodTitle(Mage::helper('shipping')->__($rate['delivery_type']));
	
					$shippingPrice = $this->getFinalPriceWithHandlingFee($rate['price']);
					$method->setCost($rate['cost']);
					$method->setDeliveryType($rate['delivery_type']);
	        		
					$method->setPrice($shippingPrice);
	
					$result->append($method);
				}
			}
		}
	   
        return $result;
    }

    public function getRate(Mage_Shipping_Model_Rate_Request $request)
    {
        return Mage::getResourceModel('cshipping/carrier_dhl')->getNewRate($request,$this->getConfigFlag('zip_range'), $this->_code);
    }
    
    /**
     * Get allowed shipping methods
     *
     * @return array
     */
    public function getAllowedMethods()
    {
        return array($this->_code=>$this->getConfigData('name'));
    }
    

    public function getCode($type, $code='')
    {
        $codes = array(

            'condition_name'=>array(
                'package_weight' => Mage::helper('shipping')->__('Weight vs. Destination'),
                'package_value'  => Mage::helper('shipping')->__('Price vs. Destination'),
                'package_qty'    => Mage::helper('shipping')->__('# of Items vs. Destination'),
            ),

            'condition_name_short'=>array(
                'package_weight' => Mage::helper('shipping')->__('Weight'),
                'package_value'  => Mage::helper('shipping')->__('Order Subtotal'),
                'package_qty'    => Mage::helper('shipping')->__('# of Items'),
            ),

        );

        if (!isset($codes[$type])) {
            throw Mage::exception('Mage_Shipping', Mage::helper('shipping')->__('Invalid DHL code type: %s', $type));
        }

        if (''===$code) {
            return $codes[$type];
        }

        if (!isset($codes[$type][$code])) {
            throw Mage::exception('Mage_Shipping', Mage::helper('shipping')->__('Invalid DHL code for type %s: %s', $type, $code));
        }

        return $codes[$type][$code];
    }

    protected function _getItemWeight2($id)
    {
    	$product = Mage::getModel('catalog/product')->load($id);
    	$weight2 = floatval(trim($product->getWeight2()));
    	return !empty($weight2) ? $weight2 : null;
    }
}
